package com.aijk.web.admin.intercept;

import com.aijk.base.entity.RecordState;
import com.aijk.commons.exception.ErrorCodeConst;
import com.aijk.commons.exception.ErrorCodeException;
import com.aijk.commons.utils.CheckUtils;
import com.aijk.commons.utils.SignUtils;
import com.aijk.commons.web.utils.ParamsUtils;
import com.aijk.commons.web.utils.WebUtils;

import com.alibaba.dubbo.config.annotation.Reference;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Clock;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>系统级参数解析</p>
 * Created by iscdw on 2016/5/21.
 */
public class SystemParamIntercept implements HandlerInterceptor {

    private final Logger logger = LoggerFactory.getLogger(SystemParamIntercept.class);

    private final HashMap<String, String > APP_VERIFICATIONS = new HashMap<String, String>(){{
        put("8cc6388df5fc49a29c70106f0dbf9add","a3a0412fcb4b49f48d0dce092a3a9ce2");
    }};
    /**
     * 最大时间误差为10分钟
     */
    private final long INTERVAL = 1000 * 60 * 10;
    /**
     * 时间戳格式
     */
    private final String FORMAT = "yyyyMMddHHmmss";


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        long time1 = System.currentTimeMillis();
        String sign = request.getParameter("sign");
        //接口版本号
        String v = request.getParameter("v");
        //APP版本号
        String version = request.getParameter("version");
        String timestamp = request.getParameter("timestamp");
        String openid = request.getParameter("openid");
        String token = request.getParameter("token");
        String debug = request.getParameter("_debug_");
        String apiUri = request.getRequestURI();
        // 验证URL是/app开头的
        if (apiUri.indexOf("/app") == 0) {
            if (StringUtils.isEmpty(debug)) {
                CheckUtils.check(ErrorCodeConst.USER_MODULE_SERVE, sign, "sign");
                CheckUtils.check(ErrorCodeConst.USER_MODULE_SERVE, timestamp, "timestamp");
                CheckUtils.check(ErrorCodeConst.USER_MODULE_SERVE, openid, "openid");
                CheckUtils.check(ErrorCodeConst.USER_MODULE_SERVE, version, "version");

            }

            // 校验API TODO 校验接口是否存在或则禁用
         //   EopApi api = checkApi(apiUri, version);

           // api.setSign(EopApiConst.NEED_SIGN);

            // 如果需要则校验签名
            if (StringUtils.isEmpty(debug)) {
                // 校验APP
              //  EopApp app = checkApp(openid);
                if(!APP_VERIFICATIONS.containsKey(openid)){
                    throw new ErrorCodeException(ErrorCodeConst.GLOBAL_REQUEST_ERROR, "app_key无效");
                }

                // 校验时间戳
                CheckUtils.checkDate(ErrorCodeConst.USER_MODULE_SERVE, timestamp, FORMAT, "timestamp");

                Date reqDate = DateUtils.parseDate(timestamp, FORMAT);
                if (Math.abs(Clock.systemDefaultZone().millis() - reqDate.getTime()) > INTERVAL) {
                    throw new ErrorCodeException(ErrorCodeConst.GLOBAL_REQUEST_ERROR, "请求已过期");
                }
                checkSign(APP_VERIFICATIONS.get(openid), sign, request);

           /*     ApiContext.getContext().setAppid(app.getAppId());
                ApiContext.getContext().setAppCode(app.getAppCode());
                ApiContext.getContext().setPlatform(app.getPlatform());*/
            }
            // 存储线程变量
           /* ApiContext.getContext().setAppKey(openid);
            ApiContext.getContext().setVersion(version);
            ApiContext.getContext().setClientIp(WebUtils.getRequestIP(request));
            if (StringUtils.isNotBlank(token)) {
                Long uid = userOperateApi.getUserIdByToken(token);
                if(uid != null && uid > 0 ){
                    ApiContext.getContext().setUid(uid);
                }else{//token失效需要重新登录
                    throw new ErrorCodeException(ErrorCodeConst.OPENAPI_MODULE_SERVE+ ErrorCodeConstant.CODE_009999, ErrorMessageConstant.MSG_000009999);
                }
            }else{
                ApiContext.getContext().setUid(null);
            }*/
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) throws Exception {

    }

   /* public EopApi checkApi(String method, String version) {
        *//*if (StringUtils.isEmpty(version)) {
            version = "1.0.0";
        }
        EopApi api = ApiConst.APIS.get(method + version);
        if (api == null) {
            throw new ErrorCodeException(ErrorCodeConst.GLOBAL_REQUEST_ERROR, "Api接口不存在请确认[method]参数是否正确");
        }
        if (api.getStatus().byteValue() == RecordState.USE.status()) {
            throw new ErrorCodeException(ErrorCodeConst.GLOBAL_REQUEST_ERROR, "Api接口已禁用");
        }

        return api;*//*
        EopApi api = new EopApi();
        api.setSign(EopApiConst.NEED_SIGN);
        return api;
    }

    public EopApp checkApp(String appkey) {
        EopApp app = ApiConst.APPS.get(appkey);
        if (app == null) {
            throw new ErrorCodeException(ErrorCodeConst.GLOBAL_REQUEST_ERROR, "应用未授权请确认[openid]参数是否正确");
        }
        if (app.getStatus().byteValue() == RecordState.OFF.status()) {
            throw new ErrorCodeException(ErrorCodeConst.GLOBAL_REQUEST_ERROR, "应用已禁用");
        }
        return app;
    }*/

    public void checkSign(String secret, String sign, HttpServletRequest request) {

        CheckUtils.check(ErrorCodeConst.USER_MODULE_SERVE, sign, "sign");
        Map<String, Object> params = ParamsUtils.getParams(request);
        String sysSign = SignUtils.getSignature(params, secret);

        if (!sysSign.equalsIgnoreCase(sign)) {
            throw new ErrorCodeException(ErrorCodeConst.GLOBAL_REQUEST_ERROR, "请求签名无效,请确认[sign]参数是否正确");
        }
    }

}


